package com.sunwayworld.basemodule.business.batchrevise.service.impl;

import com.sunwayworld.basemodule.business.batch.bean.LimsBatchBean;
import com.sunwayworld.basemodule.business.batch.bean.LimsBatchSampleBean;
import com.sunwayworld.basemodule.business.batch.bean.LimsBatchSampleProductBean;
import com.sunwayworld.basemodule.business.batch.service.LimsBatchSampleProductService;
import com.sunwayworld.basemodule.business.batch.service.LimsBatchSampleService;
import com.sunwayworld.basemodule.business.batch.service.LimsBatchService;
import com.sunwayworld.basemodule.business.batchrevise.bean.LimsBatchSampleProductTempBean;
import com.sunwayworld.basemodule.business.batchrevise.bean.LimsBatchSampleTempBean;
import com.sunwayworld.basemodule.business.batchrevise.bean.LimsSampleTempBean;
import com.sunwayworld.basemodule.business.batchrevise.service.LimsBatchSampleProductTempService;
import com.sunwayworld.basemodule.business.batchrevise.service.LimsBatchSampleTempService;
import com.sunwayworld.basemodule.business.batchrevise.service.LimsSampleTempService;
import com.sunwayworld.basemodule.common.auditrecord.service.LimsAuditRecordService;
import com.sunwayworld.basemodule.samplemanage.sample.bean.LimsSampleBean;
import com.sunwayworld.basemodule.samplemanage.sample.service.LimsSampleService;
import com.sunwayworld.framework.audit.aunnotation.Audit;
import com.sunwayworld.framework.constant.Constant;
import com.sunwayworld.framework.mybatis.mapper.MapperParameter;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.support.auditable.bean.CoreBpmnParameterDTO;
import com.sunwayworld.framework.utils.BeanUtils;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.service.CoreFileService;
import com.sunwayworld.module.sys.bpmn.bean.CoreBpmnInstanceStatusDTO;
import com.sunwayworld.module.sys.bpmn.engine.CoreBpmnRuntimeService;
import com.sunwayworld.module.sys.bpmn.engine.CoreBpmnRuntimeSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.business.batchrevise.dao.LimsBatchReviseDao;
import com.sunwayworld.basemodule.business.batchrevise.bean.LimsBatchReviseBean;
import com.sunwayworld.basemodule.business.batchrevise.service.LimsBatchReviseService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsBatchReviseServiceImpl implements LimsBatchReviseService {

    @Autowired
    private LimsBatchReviseDao limsBatchReviseDao;

    @Lazy
    @Autowired
    private LimsBatchService batchService;

    @Lazy
    @Autowired
    private LimsBatchSampleTempService batchSampleTempService;

    @Lazy
    @Autowired
    private LimsSampleTempService sampleTempService;

    @Lazy
    @Autowired
    private LimsBatchSampleProductTempService batchSampleProductTempService;

    @Autowired
    @Lazy
    private LimsAuditRecordService auditRecordService;

    @Lazy
    @Autowired
    private LimsBatchSampleProductService batchSampleProductService;

    @Lazy
    @Autowired
    private LimsBatchSampleService batchSampleService;

    @Lazy
    @Autowired
    private LimsSampleService sampleService;

    @Lazy
    @Autowired
    private CoreFileService fileService;

    @Override
    @SuppressWarnings("unchecked")
    public LimsBatchReviseDao getDao() {
        return limsBatchReviseDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsBatchReviseBean limsBatchRevise = jsonWrapper.parseUnique(LimsBatchReviseBean.class);
        LimsBatchBean batchBean = batchService.selectById(limsBatchRevise.getBatchId());
        BeanUtils.copyProperties(batchBean, limsBatchRevise, "id", "status", "createdById", "createdByName", "createdTime", "createdByOrgId", "createdByOrgName");
        limsBatchRevise.setId(ApplicationContextHelper.getNextIdentity());
        limsBatchRevise.setBatchId(batchBean.getId());
        getDao().insert(limsBatchRevise);
        saveBatchInfo(limsBatchRevise);
        return limsBatchRevise.getId();
    }

    private void saveBatchInfo(LimsBatchReviseBean reviseBean) {
        LimsBatchBean batchBean = batchService.selectById(reviseBean.getBatchId());
        batchBean.setReviseFlag(Constant.YES);
        batchService.getDao().update(batchBean, "reviseFlag");

        List<LimsBatchSampleBean> batchSampleBeans = batchSampleService.selectListByFilter(SearchFilter.instance().match("batchId", batchBean.getId()).filter(MatchPattern.EQ));

        List<Long> sampleIds = batchSampleBeans.stream().map(LimsBatchSampleBean::getSampleId).collect(Collectors.toList());
        List<LimsSampleBean> sampleBeans = sampleService.selectListByIds(sampleIds);
        List<LimsSampleTempBean> sampleTempBeans = sampleBeans.stream().map(m -> {
            LimsSampleTempBean e = new LimsSampleTempBean();
            BeanUtils.copyProperties(m, e);
            e.setId(ApplicationContextHelper.getNextIdentity());
            e.setSampleId(m.getId());
            return e;
        }).collect(Collectors.toList());
        sampleTempService.getDao().insert(sampleTempBeans);

        List<LimsBatchSampleTempBean> batchSampleTempBeans = batchSampleBeans.stream().map(m -> {
            LimsSampleTempBean sampleTempBean = sampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
            LimsBatchSampleTempBean e = new LimsBatchSampleTempBean();
            BeanUtils.copyProperties(m, e);
            e.setId(ApplicationContextHelper.getNextIdentity());
            e.setReviseId(reviseBean.getId());
            e.setSampleTempId(sampleTempBean.getId());
            e.setBatchSampleId(m.getId());
            return e;
        }).collect(Collectors.toList());
        batchSampleTempService.getDao().insert(batchSampleTempBeans);

        List<LimsBatchSampleProductBean> batchSampleProjectBeans = batchSampleProductService.selectListByFilter(SearchFilter.instance().match("batchId", reviseBean.getBatchId()).filter(MatchPattern.EQ));
        List<LimsBatchSampleProductTempBean> batchSampleProjectTempBeans = batchSampleProjectBeans.stream().map(m -> {
            LimsBatchSampleTempBean batchSampleTempBean = batchSampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
            LimsBatchSampleProductTempBean e = new LimsBatchSampleProductTempBean();
            BeanUtils.copyProperties(m, e);
            e.setId(ApplicationContextHelper.getNextIdentity());
            e.setReviseId(reviseBean.getId());
            e.setBatchSampleTempId(batchSampleTempBean.getId());
            e.setSampleTempId(batchSampleTempBean.getSampleTempId());
            return e;
        }).collect(Collectors.toList());
        batchSampleProductTempService.getDao().insert(batchSampleProjectTempBeans);
        fileService.copy("T_LIMS_BATCH$" + batchBean.getId(), "T_LIMS_BATCH_REVISE$" + reviseBean.getId());
    }

    @Transactional
    @Override
    public void delete(RestJsonWrapperBean wrapper) {
        List<LimsBatchReviseBean> parse = wrapper.parse(LimsBatchReviseBean.class);
        if (CollectionUtils.isEmpty(parse)) return;
        delete(parse);
    }

    private void delete(List<LimsBatchReviseBean> batchReviseBeans) {
        if (CollectionUtils.isEmpty(batchReviseBeans)) return;
        List<Long> reviseIds = batchReviseBeans.stream().map(LimsBatchReviseBean::getId).collect(Collectors.toList());
        List<LimsBatchReviseBean> batchRevises = selectListByIds(reviseIds);
        List<LimsBatchSampleTempBean> batchSampleBeans = batchSampleTempService.selectListByFilter(SearchFilter.instance()
                .match("reviseId", reviseIds).filter(MatchPattern.OR));
        if (!CollectionUtils.isEmpty(batchSampleBeans)) {
            List<Long> sampleTempIds = batchSampleBeans.stream().map(LimsBatchSampleTempBean::getSampleTempId).collect(Collectors.toList());
            sampleTempService.getDao().deleteByIdList(sampleTempIds);
            batchSampleTempService.getDao().deleteBy(batchSampleBeans);
        }
        List<LimsBatchSampleProductTempBean> productTempBeans = reviseIds.stream().map(id -> {
            LimsBatchSampleProductTempBean productTempBean = new LimsBatchSampleProductTempBean();
            productTempBean.setReviseId(id);
            return productTempBean;
        }).collect(Collectors.toList());
        batchSampleProductTempService.getDao().deleteBy(productTempBeans, "reviseId");
        getDao().deleteBy(batchReviseBeans);
        //还原订单状态
        LimsBatchBean batchBean = new LimsBatchBean();
        batchBean.setReviseFlag(Constant.NO);
        // 订单IDS
        List<Long> batchIds = batchRevises.stream().map(LimsBatchReviseBean::getBatchId).collect(Collectors.toList());
        batchService.getDao().updateByIds(batchBean, batchIds, "reviseFlag");
    }

    @Transactional
    @Override
    public void batchSubmit(RestJsonWrapperBean wrapper) {
        List<LimsBatchReviseBean> reviseBeans = wrapper.parse(LimsBatchReviseBean.class);
        if (CollectionUtils.isEmpty(reviseBeans)) return;
        reviseBeans.forEach(r -> r.setStatus("approve"));
        getDao().update(reviseBeans, "status");
    }

    @Transactional
    @Override
    public void submitById(Long id, RestJsonWrapperBean wrapper) {
        LimsBatchReviseBean reviseBean = selectByIdIfPresent(id);
        if (reviseBean != null) {
            reviseBean.setStatus("approve");
            getDao().update(reviseBean, "status");
        }

    }

    @Transactional
    @Override
    public void approve(RestJsonWrapperBean wrapper) {
        List<LimsBatchReviseBean> reviseBeans = wrapper.parse(LimsBatchReviseBean.class);
        if (CollectionUtils.isEmpty(reviseBeans)) return;
        List<String> status = Arrays.asList("1", "2");
        List<LimsBatchReviseBean> baseProductList = reviseBeans.stream().filter(r -> status.contains(r.getReviseType())).collect(Collectors.toList());
        backBatchInfo(reviseBeans); // 备份历史数据
        copyInfoAndProduct(baseProductList);  // 同步临时表数据到主表
        delete(reviseBeans);  // 清除临时表
    }

    // 备份订单信息历史信息
    private void backBatchInfo(List<LimsBatchReviseBean> reviseBeans) {
        if (CollectionUtils.isEmpty(reviseBeans)) return;
        List<Long> batchIds = reviseBeans.stream().map(LimsBatchReviseBean::getBatchId).collect(Collectors.toList());
        List<LimsBatchBean> batchBeans = batchService.selectListByIds(batchIds);

        List<LimsBatchSampleBean> batchSampleBeans = batchSampleService.selectListByFilter(SearchFilter.instance().match("batchId", batchIds).filter(MatchPattern.OR));
        List<Long> sampleIds = batchSampleBeans.stream().map(LimsBatchSampleBean::getSampleId).collect(Collectors.toList());
        List<LimsSampleBean> sampleBeans = sampleService.selectListByIds(sampleIds);
        List<LimsBatchSampleProductBean> batchSampleProjectBeans = batchSampleProductService.selectListByFilter(SearchFilter.instance().match("batchId", batchIds).filter(MatchPattern.OR));

        List<LimsBatchReviseBean> reviseList = new ArrayList<>();
        List<LimsSampleTempBean> sampleTempBeans = new ArrayList<>();
        List<LimsBatchSampleTempBean> batchSampleTempBeans = new ArrayList<>();
        List<LimsBatchSampleProductTempBean> batchSampleProjectTempBeans = new ArrayList<>();
        // 复制历史数据
        for (LimsBatchBean batchBean : batchBeans) {
            LimsBatchReviseBean revise = reviseBeans.stream().filter(r ->
                    r.getBatchId().equals(batchBean.getId())).findFirst().get();
            LimsBatchReviseBean reviseBean = new LimsBatchReviseBean();
            BeanUtils.copyProperties(batchBean, reviseBean, "id", "status", "createdById", "createdByName", "createdTime", "createdByOrgId", "createdByOrgName");
            reviseBean.setId(ApplicationContextHelper.getNextIdentity());
            reviseBean.setBatchId(batchBean.getId());
            reviseBean.setType("history");
            reviseBean.setReviseType(revise.getReviseType());
            reviseBean.setStatus("done");
            reviseList.add(reviseBean);

            List<LimsBatchSampleBean> batchSampleList = batchSampleBeans.stream().filter(b -> b.getBatchId().equals(batchBean.getId())).collect(Collectors.toList());
            List<LimsSampleBean> sampleList = sampleBeans.stream().filter(s -> batchSampleList.stream().anyMatch(b -> b.getSampleId().equals(s.getId()))).collect(Collectors.toList());
            List<LimsBatchSampleProductBean> batchSampleProductList = batchSampleProjectBeans.stream().filter(s -> batchSampleList.stream().anyMatch(b -> b.getId().equals(s.getBatchSampleId()))).collect(Collectors.toList());

            sampleTempBeans.addAll(sampleList.stream().map(m -> {
                LimsSampleTempBean e = new LimsSampleTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setSampleId(m.getId());
                return e;
            }).collect(Collectors.toList()));

            batchSampleTempBeans.addAll(batchSampleList.stream().map(m -> {
                LimsSampleTempBean sampleTempBean = sampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
                LimsBatchSampleTempBean e = new LimsBatchSampleTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setReviseId(reviseBean.getId());
                e.setSampleTempId(sampleTempBean.getId());
                e.setBatchSampleId(m.getId());
                return e;
            }).collect(Collectors.toList()));


            batchSampleProjectTempBeans.addAll(batchSampleProductList.stream().map(m -> {
                LimsBatchSampleTempBean batchSampleTempBean = batchSampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
                LimsBatchSampleProductTempBean e = new LimsBatchSampleProductTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setReviseId(reviseBean.getId());
                e.setBatchSampleTempId(batchSampleTempBean.getId());
                e.setSampleTempId(batchSampleTempBean.getSampleTempId());
                return e;
            }).collect(Collectors.toList()));
            fileService.copy("T_LIMS_BATCH$" + batchBean.getId(), "T_LIMS_BATCH_REVISE$" + reviseBean.getId());

            batchBean.setReviseFlag("0");
        }
        getDao().insert(reviseList);
        sampleTempService.getDao().insert(sampleTempBeans);
        batchSampleTempService.getDao().insert(batchSampleTempBeans);
        batchSampleProductTempService.getDao().insert(batchSampleProjectTempBeans);
        batchService.getDao().update(batchBeans, "reviseFlag");
    }

    @Transactional
    @AuditTrailEntry(AuditTrailType.PROCESS_COMPLETE)
    @Audit("AUDIT.PROCESS_COMPLETE")
    public List<CoreBpmnInstanceStatusDTO<Long>> completeTask(RestJsonWrapperBean wrapper) {
        List<LimsBatchReviseBean> itemList = wrapper.parse(LimsBatchReviseBean.class);
        if (itemList.isEmpty()) {
            return CollectionUtils.emptyList();
        } else {
            this.checkAndUpdateVersion(itemList);
            CoreBpmnRuntimeService runtimeService = ApplicationContextHelper.getBean(CoreBpmnRuntimeService.class);
            List<Long> itemIdList = itemList.stream().map(LimsBatchReviseBean::getId).collect(Collectors.toList());
            List<LimsBatchReviseBean> selectItemList = this.getBpmnVarsItemList(itemIdList);
            List<CoreBpmnRuntimeSource<LimsBatchReviseBean, Long>> runtimeSourceList = this.parseAuditableRuntimeSource(itemIdList, CoreBpmnParameterDTO.of(wrapper), this.getBpmnVars(wrapper, selectItemList));
            List<CoreBpmnInstanceStatusDTO<Long>> instanceStatusList = runtimeService.completeTask(runtimeSourceList);
            this.autoPass(runtimeSourceList, instanceStatusList);
            selectItemList = this.selectListByIds(itemIdList);

            List<String> status = Arrays.asList("1", "2");
            List<LimsBatchReviseBean> baseProductList = selectItemList.stream().filter(r -> status.contains(r.getReviseType())).collect(Collectors.toList());

            List<LimsBatchReviseBean> reviseList = new ArrayList<>();
            List<LimsSampleTempBean> sampleTempBeans = new ArrayList<>();
            List<LimsBatchSampleTempBean> batchSampleTempBeans = new ArrayList<>();
            List<LimsBatchSampleProductTempBean> batchSampleProjectTempBeans = new ArrayList<>();
            backBatchInfo2(selectItemList, reviseList, sampleTempBeans, batchSampleTempBeans, batchSampleProjectTempBeans); // 备份历史数据
            copyInfoAndProduct(baseProductList);  // 同步临时表数据到主表

            delete(selectItemList);  // 清除临时表

            getDao().insert(reviseList);
            sampleTempService.getDao().insert(sampleTempBeans);
            batchSampleTempService.getDao().insert(batchSampleTempBeans);
            batchSampleProductTempService.getDao().insert(batchSampleProjectTempBeans);

            return instanceStatusList;
        }
    }

    // 备份订单信息历史信息
    @Transactional
    public void backBatchInfo2(List<LimsBatchReviseBean> reviseBeans, List<LimsBatchReviseBean> reviseList, List<LimsSampleTempBean> sampleTempBeans, List<LimsBatchSampleTempBean> batchSampleTempBeans, List<LimsBatchSampleProductTempBean> batchSampleProjectTempBeans) {
        if (CollectionUtils.isEmpty(reviseBeans)) return;
        List<Long> batchIds = reviseBeans.stream().map(LimsBatchReviseBean::getBatchId).collect(Collectors.toList());
        List<LimsBatchBean> batchBeans = batchService.selectListByIds(batchIds);

        List<LimsBatchSampleBean> batchSampleBeans = batchSampleService.selectListByFilter(SearchFilter.instance().match("batchId", batchIds).filter(MatchPattern.OR));
        List<Long> sampleIds = batchSampleBeans.stream().map(LimsBatchSampleBean::getSampleId).collect(Collectors.toList());
        List<LimsSampleBean> sampleBeans = sampleService.selectListByIds(sampleIds);
        List<LimsBatchSampleProductBean> batchSampleProjectBeans = batchSampleProductService.selectListByFilter(SearchFilter.instance().match("batchId", batchIds).filter(MatchPattern.OR));

        // 复制历史数据
        for (LimsBatchBean batchBean : batchBeans) {
            LimsBatchReviseBean revise = reviseBeans.stream().filter(r ->
                    r.getBatchId().equals(batchBean.getId())).findFirst().get();
            LimsBatchReviseBean reviseBean = new LimsBatchReviseBean();
            BeanUtils.copyProperties(batchBean, reviseBean, "id", "status", "createdById", "createdByName", "createdTime", "createdByOrgId", "createdByOrgName");
//            reviseBean.setId(ApplicationContextHelper.getNextIdentity());
            reviseBean.setId(revise.getId());// 用原来的id，省的工作流查不到记录
            reviseBean.setBatchId(batchBean.getId());
            reviseBean.setType("history");
            reviseBean.setReviseType(revise.getReviseType());
            reviseBean.setStatus("done");
            reviseBean.setProcessStatus("done");
            reviseList.add(reviseBean);

            List<LimsBatchSampleBean> batchSampleList = batchSampleBeans.stream().filter(b -> b.getBatchId().equals(batchBean.getId())).collect(Collectors.toList());
            List<LimsSampleBean> sampleList = sampleBeans.stream().filter(s -> batchSampleList.stream().anyMatch(b -> b.getSampleId().equals(s.getId()))).collect(Collectors.toList());
            List<LimsBatchSampleProductBean> batchSampleProductList = batchSampleProjectBeans.stream().filter(s -> batchSampleList.stream().anyMatch(b -> b.getId().equals(s.getBatchSampleId()))).collect(Collectors.toList());

            sampleTempBeans.addAll(sampleList.stream().map(m -> {
                LimsSampleTempBean e = new LimsSampleTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setSampleId(m.getId());
                return e;
            }).collect(Collectors.toList()));

            batchSampleTempBeans.addAll(batchSampleList.stream().map(m -> {
                LimsSampleTempBean sampleTempBean = sampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
                LimsBatchSampleTempBean e = new LimsBatchSampleTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setReviseId(reviseBean.getId());
                e.setSampleTempId(sampleTempBean.getId());
                e.setBatchSampleId(m.getId());
                return e;
            }).collect(Collectors.toList()));


            batchSampleProjectTempBeans.addAll(batchSampleProductList.stream().map(m -> {
                LimsBatchSampleTempBean batchSampleTempBean = batchSampleTempBeans.stream().filter(s -> s.getSampleId().equals(m.getSampleId())).findFirst().get();
                LimsBatchSampleProductTempBean e = new LimsBatchSampleProductTempBean();
                BeanUtils.copyProperties(m, e);
                e.setId(ApplicationContextHelper.getNextIdentity());
                e.setReviseId(reviseBean.getId());
                e.setBatchSampleTempId(batchSampleTempBean.getId());
                e.setSampleTempId(batchSampleTempBean.getSampleTempId());
                return e;
            }).collect(Collectors.toList()));
//            fileService.copy("T_LIMS_BATCH$" + batchBean.getId(), "T_LIMS_BATCH_REVISE$" + reviseBean.getId());

            batchBean.setReviseFlag("0");
        }
        batchService.getDao().update(batchBeans, "reviseFlag");
    }

    // 修改基本信息和产品
    private void copyInfoAndProduct(List<LimsBatchReviseBean> reviseBeans) {
        if (CollectionUtils.isEmpty(reviseBeans)) return;
        List<Long> reviseIds = reviseBeans.stream().map(LimsBatchReviseBean::getId).collect(Collectors.toList());
        List<Long> batchIds = reviseBeans.stream().map(LimsBatchReviseBean::getBatchId).collect(Collectors.toList());
        MapperParameter parameter = new MapperParameter();
        parameter.setFilter(SearchFilter.instance()
                .match("reviseId", reviseIds).filter(MatchPattern.OR));
        List<LimsSampleTempBean> tempBeans = batchSampleTempService.selectBatchSampleInfo(parameter);

        List<LimsSampleBean> updateBeans = tempBeans.stream().map(t -> {
            ((LimsSampleBean) t).setId(t.getSampleId());
            return (LimsSampleBean) t;
        }).collect(Collectors.toList());
        sampleService.getDao().updateIfChanged(updateBeans);

        parameter.clear();
        parameter.setFilter(SearchFilter.instance().match("batchId", batchIds).filter(MatchPattern.OR));
        List<LimsSampleBean> sampleBeans = batchSampleService.selectBatchSample(parameter);

        List<LimsSampleTempBean> productChanges = new ArrayList<>();
        for (LimsSampleBean sampleBean : sampleBeans) {
            Optional<LimsSampleTempBean> first = tempBeans.stream().filter(t -> t.getSampleId().equals(sampleBean.getId())).findFirst();
            first.ifPresent(s -> {
                if (!s.getExt$Item("productNames").equalsIgnoreCase(sampleBean.getExt$Item("productNames"))) {
                    productChanges.add(s);
                }
            });
        }

        if (!CollectionUtils.isEmpty(productChanges)) {
            List<Long> batchSampleTempIds = productChanges.stream().map(p -> p.getExt$Item("batchSampleTempId"))
                    .map(Long::parseLong).collect(Collectors.toList());
            List<Long> batchSampleIds = productChanges.stream().map(p -> p.getExt$Item("batchSampleId"))
                    .map(Long::parseLong).collect(Collectors.toList());
            // 删除原来产品
            List<LimsBatchSampleProductBean> deleteBeans = batchSampleIds.stream().map(id -> {
                LimsBatchSampleProductBean deleteBean = new LimsBatchSampleProductBean();
                deleteBean.setBatchSampleId(id);
                return deleteBean;
            }).collect(Collectors.toList());
            batchSampleProductService.getDao().deleteBy(deleteBeans, "batchSampleId");

            List<LimsBatchSampleProductTempBean> productTempBeans = batchSampleProductTempService.selectListByFilter(SearchFilter.instance()
                    .match("batchSampleTempId", batchSampleTempIds).filter(MatchPattern.OR));
            List<LimsBatchSampleProductBean> productBeans = productTempBeans.stream()
                    .map(p -> (LimsBatchSampleProductBean) p).collect(Collectors.toList());
            batchSampleProductService.getDao().insert(productBeans);
        }
        List<CoreFileBean> reviseAtts = fileService.selectFileListByTargetIds(reviseBeans.stream().map(s -> "T_LIMS_BATCH_REVISE$" + s.getId()).toArray(String[]::new)); // 报告附件
        List<CoreFileBean> batchAtts = fileService.selectFileListByTargetIds(reviseBeans.stream().map(s -> "T_LIMS_BATCH$" + s.getBatchId()).toArray(String[]::new)); // 报告附件
        List<CoreFileBean> updateFileBeans = new ArrayList<>();
        reviseBeans.forEach(revise -> {
            List<CoreFileBean> rFileBeans = reviseAtts.stream().filter(f -> f.getTargetId()
                    .equalsIgnoreCase("T_LIMS_BATCH_REVISE$" + revise.getId())).collect(Collectors.toList());
            rFileBeans.forEach(f -> f.setTargetId("T_LIMS_BATCH$" + revise.getBatchId()));
            updateFileBeans.addAll(rFileBeans);
            List<CoreFileBean> bFileBeans = batchAtts.stream().filter(f -> f.getTargetId()
                    .equalsIgnoreCase("T_LIMS_BATCH$" + revise.getBatchId())).collect(Collectors.toList());
            bFileBeans.forEach(f -> f.setTargetId("T_LIMS_BATCH_REVISE$" + revise.getId()));
            updateFileBeans.addAll(bFileBeans);
        });
        fileService.getDao().update(updateFileBeans, "targetId");
    }


    @Transactional
    @Override
    public void reject(RestJsonWrapperBean wrapper) {
        List<LimsBatchReviseBean> reviseBeans = wrapper.parse(LimsBatchReviseBean.class);
        if (CollectionUtils.isEmpty(reviseBeans)) return;

        reviseBeans.forEach(r -> r.setStatus("draft_rejct"));
        getDao().update(reviseBeans, "status");
    }

    @Transactional
    @Override
    public void approveById(Long id, RestJsonWrapperBean wrapper) {
        LimsBatchReviseBean limsBatchReviseBean = selectByIdIfPresent(id);
        if (limsBatchReviseBean == null) return;
        List<LimsBatchReviseBean> reviseBeans = Collections.singletonList(limsBatchReviseBean);
        backBatchInfo(reviseBeans); // 备份历史数据
        copyInfoAndProduct(reviseBeans);  // 同步临时表数据到主表
        delete(reviseBeans);  // 清除临时表
    }

    @Transactional
    @Override
    public void rejectById(Long id, RestJsonWrapperBean wrapper) {
        LimsBatchReviseBean limsBatchReviseBean = selectByIdIfPresent(id);
        if (limsBatchReviseBean == null) return;

        limsBatchReviseBean.setStatus("draft_rejct");
        getDao().update(limsBatchReviseBean, "status");
    }
}
